package com.agan.jvm.test01.lesson08;

import java.io.*;
/**
 * @author 阿甘
 * @see https://study.163.com/course/introduction/1211562809.htm?share=1&shareId=1028852228
 * @version 1.0
 * 注：如有任何疑问,欢迎加阿甘老师微信agan-java 进行讨论
 */
public class MyClassLoader extends ClassLoader {
    //类加载器的名称
    private String name;
    //类存放的路径
    private String path ;

    public void setPath(String path) {
        this.path = path;
    }

    public MyClassLoader(String name) {
        this.name = name;
    }
    MyClassLoader(ClassLoader parent, String name) {
        // 指定该类加载器的父加载器
        super(parent);
        this.name = name;
    }
    /**
     *重写其findClass()方法
     *查找名称为 name 的类，返回的结果是 java.lang.Class 类的实例。
     */
    @Override
    public Class<?> findClass(String name) {
        //找到或者生成其对应的字节代码
        byte[] data = getDatas(name);
        //从这些字节代码中生成一个java.lang.Class 实例
        return this.defineClass(name, data, 0, data.length);
    }

    /**
     * 读取Class字节流
     * @return
     */
    private byte[] getDatas(String name) {
        name = name.replace(".", "/");
        File file=new File(path + name + ".class");
        System.out.println("加载二进制文件:"+file.getPath());

        FileInputStream in = null;
        ByteArrayOutputStream outputStream = null;
        if(file.exists()){
            try {
                in = new FileInputStream(file);
                outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int size = 0;
                while ((size = in.read(buffer)) != -1){
                    outputStream.write(buffer,0,size);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return outputStream.toByteArray();
        }
        return null;
    }

}

